#include "CRemoteThread.h"

CRemoteThread::CRemoteThread(void)
{
	memset(m_szTargetProcessName, 0, sizeof(TCHAR) * MAX_PATH);
	memset(&m_psEntry, 0, sizeof(PROCESSENTRY32));
	m_psEntry.dwSize =sizeof(m_psEntry);
	
	m_hTargetProcess = NULL;	
}

CRemoteThread::~CRemoteThread(void)
{
}

BOOL CRemoteThread::InitializeTargetProcess(TCHAR* szProcessName)
{ 
 
	HANDLE hSnapShot;	
	BOOL bRes = FALSE;

	hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPALL,NULL);	
	
	bRes = Process32First(hSnapShot, &m_psEntry);
	
	while(hSnapShot != NULL && bRes != FALSE)
	{
		if(0 == _tcscmp(szProcessName, m_psEntry.szExeFile))
		{
			return TRUE;
		}

		bRes = Process32Next( hSnapShot, &m_psEntry);		
	}

	return FALSE;
}

BOOL CRemoteThread::GetTargetProcessHandle()
{ 
 
	m_hTargetProcess = ::OpenProcess(MAXIMUM_ALLOWED, FALSE, m_psEntry.th32ProcessID);

	if(NULL == m_hTargetProcess)
		return FALSE;

	return TRUE;
}

BOOL CRemoteThread::InjectDLL(TCHAR* szDllName)
{ 
	TCHAR szDirectoryPath[MAX_PATH];
 
	GetCurrentDirectory(MAX_PATH, szDirectoryPath);
	lstrcat(szDirectoryPath,_TEXT("\\"));
	lstrcat(szDirectoryPath, szDllName);

	TCHAR* szRemoteDllName = NULL;
	LPVOID lpLoadLibrary = NULL;
	HANDLE hRemoteThread = NULL;
	DWORD dwRemote = 0;

	DWORD A = _tcsclen(szDirectoryPath);

	szRemoteDllName = (TCHAR*)VirtualAllocEx(m_hTargetProcess,NULL, sizeof(TCHAR) * _tcsclen(szDirectoryPath), MEM_COMMIT, PAGE_READWRITE);
	if(NULL == szRemoteDllName) 
	{
		CloseHandle(m_hTargetProcess);
		return FALSE;
	}

	if(!WriteProcessMemory(m_hTargetProcess,szRemoteDllName,szDirectoryPath, sizeof(TCHAR) * _tcsclen(szDirectoryPath),NULL)) 
	{
		VirtualFreeEx(m_hTargetProcess,szRemoteDllName, 0, MEM_RELEASE);
		return FALSE;
	}

	lpLoadLibrary = GetProcAddress(GetModuleHandle(_TEXT("KERNEL32.dll")),"LoadLibraryW");
	hRemoteThread = CreateRemoteThread(m_hTargetProcess,NULL,0,(LPTHREAD_START_ROUTINE)lpLoadLibrary,szRemoteDllName,0,NULL);

	if(NULL == hRemoteThread) 
	{
		VirtualFreeEx(m_hTargetProcess,szRemoteDllName,0,MEM_RELEASE);
		CloseHandle(m_hTargetProcess);
		return FALSE;
	}

	WaitForSingleObject(hRemoteThread,INFINITE);
	GetExitCodeThread(hRemoteThread,&dwRemote);
	CloseHandle(hRemoteThread);
	VirtualFreeEx(m_hTargetProcess,szRemoteDllName,0,MEM_RELEASE);
	return TRUE;			
}

BOOL CRemoteThread::StartInjection(TCHAR* pProcessName)
{
	if(FALSE == InitializeTargetProcess(pProcessName))
	{
		return FALSE;
	}

	if(FALSE == GetTargetProcessHandle())
	{
		return FALSE;
	}

	if(FALSE == InjectDLL(_T("Direct3D-Hook.dll")))
		return FALSE;

	return TRUE;
}
